﻿using System;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.SPOT;

namespace DaaseVarmer.RemoteControl
{
    public class RemoteControlListener
    {
        private int _port;
        private IRemoteControl _remoteControlHandler;
        public RemoteControlListener(int port, IRemoteControl handler)
        {
            _port = port;
            _remoteControlHandler = handler;
        }

        public void Listen()
        {
            HttpListener listener = new HttpListener("http", _port);

            try
            {
                listener.Start();
                while (true)
                {
                    HttpListenerContext c = listener.GetContext();
                    Thread t = new Thread(new ThreadStart(delegate() { HandleContext(c); }));
                    t.Start();
                }
            }
            catch (Exception e)
            {
                Debug.Print("Fejl i RemoteControlListener");
            }

            
        }

        private void HandleContext(HttpListenerContext c)
        {
            try
            {

                c.Response.Headers.Add("CH_ControlType", c.Request.Headers["CH_ControlType"]);

                switch (c.Request.Headers["CH_ControlType"])
                {
                    case "ping":
                        c.Response.Headers.Add("CH_Result", _remoteControlHandler.Ping());
                        break;

                    case "fetchLatestData":
                        SetLatestDataHeaders(c);
                        c.Response.Headers.Add("CH_Result", "OK"); // Last in case of exceptions
                        break;

                    case "fetchLatestDataAndStatus":
                        SetLatestDataHeaders(c);

                        SetStatusHeaders(c);

                        c.Response.Headers.Add("CH_Result", "OK");
                        break;

                    case "controlCommand":
                        try
                        {
                            if (HandleControlCmd(c)) 
                                c.Response.Headers.Add("CH_Result", "OK");
                        }catch
                        {
                            c.Response.Headers.Add("CH_Result", "BAD REQUEST");
                        }
                        break;

                    default:
                        c.Response.Headers.Add("CH_Result", "BAD REQUEST");
                        break;
                }

                c.Response.Close();

            }
            catch { }
        }

        private void SetLatestDataHeaders(HttpListenerContext c)
        {
            c.Response.Headers.Add("CH_IndoorTemp", _remoteControlHandler.GetSensorData(SensorType.IndoorTemp).ToString());
            c.Response.Headers.Add("CH_OutdoorTemp", _remoteControlHandler.GetSensorData(SensorType.OutdoorTemp).ToString());
            c.Response.Headers.Add("CH_SolarHeaterTemp", _remoteControlHandler.GetSensorData(SensorType.SolarHeaterTemp).ToString());
            c.Response.Headers.Add("CH_AirFlow", _remoteControlHandler.GetSensorData(SensorType.AirFlow).ToString());
        }

        private void SetStatusHeaders(HttpListenerContext c)
        {
            // Ordering important, due to interleavings
            int speed = _remoteControlHandler.GetSpeed();
            double toTemp = _remoteControlHandler.GetToTemp();
            int min = _remoteControlHandler.GetMin();
            Modes m = _remoteControlHandler.GetMode();
            c.Response.Headers.Add("CH_Mode", ModesEnumToString(m));
            switch (m)
            {
                case Modes.Auto:
                case Modes.Speed:
                    c.Response.Headers.Add("CH_Speed", speed.ToString());
                    break;

                case Modes.SpeedTemp:
                    c.Response.Headers.Add("CH_Speed", speed.ToString());
                    c.Response.Headers.Add("CH_ToTemp", toTemp.ToString());
                    break;

                case Modes.SpeedTime:
                    c.Response.Headers.Add("CH_Speed", speed.ToString());
                    c.Response.Headers.Add("CH_Min", min.ToString());
                    break;
            }
        }

        private bool HandleControlCmd(HttpListenerContext c)
        {
            string mode = c.Request.Headers["CH_ControlAction"];
            string speed = c.Request.Headers["CH_Speed"];
            string temp = c.Request.Headers["CH_ToTemp"];
            string time = c.Request.Headers["CH_Min"];

            switch(mode)
            {
                case "Auto":
                    _remoteControlHandler.SetModeAuto();
                    return true;

                case "Speed":
                    _remoteControlHandler.SetModeSpeed(int.Parse(speed));
                    return true;

                case "SpeedTemp":
                    //_remoteControlHandler.SetModeSpeedTemp(int.Parse(speed), double.Parse(temp));
                    return false;

                case "SpeedTime":
                    //_remoteControlHandler.SetModeSpeedTime(int.Parse(speed), int.Parse(time));
                    return false;               
            }
            return false;
        }

        private string ModesEnumToString(Modes mode)
        {
            switch (mode)
            {
                default:
                    
                case Modes.Auto:
                    return "Auto";
                    break;
                case Modes.Speed:
                    return "Speed";
                    break;
                case Modes.SpeedTemp:
                    return "speedTemp";
                    break;
                case Modes.SpeedTime:
                    return "SpeedTimd";
                    break;

            }
      
        }
    }
}
